package com.itheima.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.common.R;
import com.itheima.constant.TokenConstant;
import com.itheima.domain.Order;
import com.itheima.domain.OrderDetails;
import com.itheima.domain.ShoppingCart;
import com.itheima.domain.User;
import com.itheima.domain.vo.OrderVo;
import com.itheima.mapper.OrderMapper;
import com.itheima.service.OrderDetailsService;
import com.itheima.service.OrderService;
import com.itheima.service.ShoppingCartService;
import com.itheima.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private OrderService orderService;

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Autowired
    private ShoppingCartService shoppingCartService;

    @Autowired
    private OrderDetailsService orderDetailsService;

    @Autowired
    private UserService userService;

    @Override
    public R<Page<Order>> adminOrderPageSelect(String id,  Integer page, Integer pageSize) {
        // 构造分页构造器
        Page<Order> pageInfo = new Page<>(page, pageSize);
        // 构造条件
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotEmpty(id), Order::getId, id);
        // 执行查询
        page(pageInfo, queryWrapper);
        return R.success(pageInfo);
    }

    @Override
    public R<String> adminOrderUpdateStatus(Order order) {
        boolean result = updateById(order);
        if (result) {
            return R.success("修改成功");
        }
        return R.error("修改失败");
    }

    /**
     *
     * @param token 加密令牌
     * @param order  前端订单信息
     * @return 提交结果
     */
    @Override
    public R<String> clientSubmitOrder(String token,Order order) {


        String userId = getUserIdByRedis(token);
        order.setUserId(userId);
        User user = userService.getById(userId);
        order.setOrderTime(LocalDateTime.now());
        //表示已支付
        order.setStatus(2);

        order.setPhone(user.getPhone());

        order.setUserName(user.getName());
        boolean submitResult = orderService.save(order);
        // 从购物车中获取到商品信息
        LambdaQueryWrapper<ShoppingCart> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ShoppingCart::getUserId, userId);
        //获取到该用户购物车所有商品的集合
        List<ShoppingCart> shoppingCartList = shoppingCartService.list(lqw);
        ArrayList<OrderDetails> detailsArrayList=new ArrayList<>();
        int amount = 0;
        //把购物车信息添加到订单和订单详情中
        for (ShoppingCart shoppingCart : shoppingCartList) {
            Integer amount1 = shoppingCart.getAmount();
            amount = amount + amount1;
            OrderDetails orderDetails = new OrderDetails();
            orderDetails.setId(order.getId());
            orderDetails.setName(shoppingCart.getName());
            orderDetails.setNumber(shoppingCart.getNumber());
            detailsArrayList.add(orderDetails);
        }
        //把获取到的订单详情集合加入进去
        orderDetailsService.saveBatch(detailsArrayList);
        order.setAmount(amount);
        order.setNumber(order.getId());
        //清空购物车
        shoppingCartService.remove(lqw);

        boolean result = orderService.updateById(order);


        if (submitResult && result) {
            return R.success("提交成功");
        }
        return R.error("提交失败");
    }

    /**
     *
     * @param token 加密令牌
     * @param page 第几页
     * @param pageSize 页面大小
     * @return 订单信息
     */
    @Override
    public R<Page<OrderVo>> clientOrderPageSelect(String token, Integer page,  Integer pageSize) {
        String userId = getUserIdByRedis(token);
        LambdaQueryWrapper<Order> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Order::getUserId, userId);
        Page<OrderVo> pageinfo = new Page<>(page, pageSize);
        //订单对象集合
        List<Order> orderList = orderService.list(lqw);
        //获取到该用户的所有订单id
        List<String> idList = orderList.stream().map(Order::getId).collect(Collectors.toList());
        //通过用户的所有订单id获取订单详情
        List<OrderDetails> detailsList = orderDetailsService.listByIds(idList);
        //通过stream流 将订单集合和订单详情集合用id关联起来，用map方法生成的集合与原来的集合中元素的类型可以不相同
        List<OrderVo> orderVoListStream = orderList.stream().map(order -> {
            OrderVo orderVo = new OrderVo();
            //筛选出与与该订单信息id一样的订单详情信息集合
            List<OrderDetails> orderDetailsList = detailsList.stream().filter(details -> Objects.equals(order.getId(), details.getId())).collect(Collectors.toList());
            orderVo.setOrderDetails((ArrayList<OrderDetails>) orderDetailsList);
            BeanUtils.copyProperties(order, orderVo);
            //把元素返回出去
            return orderVo;
        }).collect(Collectors.toList());

        pageinfo.setRecords(orderVoListStream);

        return R.success(pageinfo);
    }

    /**
     * 通过token从redis数据库取出用户id
     * @param token 加密令牌
     * @return 用户id
     */
    private String getUserIdByRedis(String token) {
        String userStr = (String) redisTemplate.opsForValue().get(TokenConstant.USER_TOKEN_PREFIX + token);
        User user = JSON.parseObject(userStr, User.class);
        assert user != null;
        return user.getId();
    }
}
